home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Active Template Library.
- // Copyright (C) 1996-1997 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Active Template Library Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Active Template Library product.
-
- #ifndef __ATLBASE_H__
- #error atlimpl.cpp requires atlbase.h to be included first
- #endif
-
- #if defined(BCC32_COMPAT)
- #pragma warn -aus
- #endif
-
- extern "C" const IID IID_IRegistrar = {0x44EC053B,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
- #ifndef _ATL_DLL_IMPL
- extern "C" const CLSID CLSID_Registrar = {0x44EC053A,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
- #endif
-
- #include "atlconv.cpp"
- #ifdef _DEBUG
- #include <stdio.h>
- #include <stdarg.h>
- #endif
-
- #ifndef ATL_NO_NAMESPACE
- namespace ATL
- {
- #endif
-
- // used in thread pooling
- UINT CComApartment::ATL_CREATE_OBJECT = 0;
-
- #ifdef __ATLCOM_H__
-
- /////////////////////////////////////////////////////////////////////////////
- // AtlReportError
-
- HRESULT WINAPI AtlReportError(const CLSID& clsid, UINT nID, const IID& iid,
- HRESULT hRes, HINSTANCE hInst)
- {
- return AtlSetErrorInfo(clsid, (LPCOLESTR)MAKEINTRESOURCE(nID), 0, NULL, iid, hRes, hInst);
- }
-
- HRESULT WINAPI AtlReportError(const CLSID& clsid, UINT nID, DWORD dwHelpID,
- LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst)
- {
- return AtlSetErrorInfo(clsid, (LPCOLESTR)MAKEINTRESOURCE(nID), dwHelpID,
- lpszHelpFile, iid, hRes, hInst);
- }
-
- #ifndef OLE2ANSI
- HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCSTR lpszDesc,
- DWORD dwHelpID, LPCSTR lpszHelpFile, const IID& iid, HRESULT hRes)
- {
- _ASSERTE(lpszDesc != NULL);
- USES_CONVERSION;
- return AtlSetErrorInfo(clsid, A2COLE(lpszDesc), dwHelpID, A2CW(lpszHelpFile),
- iid, hRes, NULL);
- }
-
- HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCSTR lpszDesc,
- const IID& iid, HRESULT hRes)
- {
- _ASSERTE(lpszDesc != NULL);
- USES_CONVERSION;
- return AtlSetErrorInfo(clsid, A2COLE(lpszDesc), 0, NULL, iid, hRes, NULL);
- }
- #endif
-
- HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCOLESTR lpszDesc,
- const IID& iid, HRESULT hRes)
- {
- return AtlSetErrorInfo(clsid, lpszDesc, 0, NULL, iid, hRes, NULL);
- }
-
- HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,
- LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes)
- {
- return AtlSetErrorInfo(clsid, lpszDesc, dwHelpID, lpszHelpFile, iid, hRes, NULL);
- }
-
- #endif //__ATLCOM_H__
-
- /////////////////////////////////////////////////////////////////////////////
- // CComBSTR
-
- CComBSTR& CComBSTR::operator=(const CComBSTR& src)
- {
- if (m_str != src.m_str)
- {
- if (m_str)
- ::SysFreeString(m_str);
- m_str = src.Copy();
- }
- return *this;
- }
-
- CComBSTR& CComBSTR::operator=(LPCOLESTR pSrc)
- {
- ::SysFreeString(m_str);
- m_str = ::SysAllocString(pSrc);
- return *this;
- }
-
- void CComBSTR::Append(LPCOLESTR lpsz, int nLen)
- {
- int n1 = Length();
- BSTR b = SysAllocStringLen(NULL, n1+nLen);
- memcpy(b, m_str, n1*sizeof(OLECHAR));
- memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
- b[n1+nLen] = NULL;
- SysFreeString(m_str);
- m_str = b;
- }
-
- #ifndef OLE2ANSI
- void CComBSTR::Append(LPCSTR lpsz)
- {
- USES_CONVERSION;
- LPCOLESTR lpo = A2COLE(lpsz);
- Append(lpo, ocslen(lpo));
- }
-
- CComBSTR::CComBSTR(LPCSTR pSrc)
- {
- USES_CONVERSION;
- m_str = ::SysAllocString(A2COLE(pSrc));
- }
-
- CComBSTR::CComBSTR(int nSize, LPCSTR sz)
- {
- USES_CONVERSION;
- m_str = ::SysAllocStringLen(A2COLE(sz), nSize);
- }
-
- CComBSTR& CComBSTR::operator=(LPCSTR pSrc)
- {
- USES_CONVERSION;
- ::SysFreeString(m_str);
- m_str = ::SysAllocString(A2COLE(pSrc));
- return *this;
- }
- #endif
-
- HRESULT CComBSTR::ReadFromStream(IStream* pStream)
- {
- _ASSERTE(pStream != NULL);
- _ASSERTE(m_str == NULL); // should be empty
- ULONG cb;
- ULONG cbStrLen;
- HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), &cb);
- if (FAILED(hr))
- return hr;
- if (cbStrLen != 0)
- {
- //subtract size for terminating NULL which we wrote out
- //since SysAllocStringByteLen overallocates for the NULL
- m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
- if (m_str == NULL)
- hr = E_OUTOFMEMORY;
- else
- hr = pStream->Read((void*) m_str, cbStrLen, &cb);
- }
- return hr;
- }
-
- HRESULT CComBSTR::WriteToStream(IStream* pStream)
- {
- _ASSERTE(pStream != NULL);
- ULONG cb;
- ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0;
- HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
- if (FAILED(hr))
- return hr;
- return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CComVariant
-
- CComVariant& CComVariant::operator=(BSTR bstrSrc)
- {
- InternalClear();
- vt = VT_BSTR;
- bstrVal = ::SysAllocString(bstrSrc);
- if (bstrVal == NULL && bstrSrc != NULL)
- {
- vt = VT_ERROR;
- scode = E_OUTOFMEMORY;
- }
- return *this;
- }
-
- CComVariant& CComVariant::operator=(LPCOLESTR lpszSrc)
- {
- InternalClear();
- vt = VT_BSTR;
- bstrVal = ::SysAllocString(lpszSrc);
-
- if (bstrVal == NULL && lpszSrc != NULL)
- {
- vt = VT_ERROR;
- scode = E_OUTOFMEMORY;
- }
- return *this;
- }
-
- #ifndef OLE2ANSI
- CComVariant& CComVariant::operator=(LPCSTR lpszSrc)
- {
- USES_CONVERSION;
- InternalClear();
- vt = VT_BSTR;
- bstrVal = ::SysAllocString(A2COLE(lpszSrc));
-
- if (bstrVal == NULL && lpszSrc != NULL)
- {
- vt = VT_ERROR;
- scode = E_OUTOFMEMORY;
- }
- return *this;
- }
- #endif
-
- #if _MSC_VER>1020
- CComVariant& CComVariant::operator=(bool bSrc)
- {
- if (vt != VT_BOOL)
- {
- InternalClear();
- vt = VT_BOOL;
- }
- #pragma warning(disable: 4310) // cast truncates constant value
- boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
- #pragma warning(default: 4310) // cast truncates constant value
- return *this;
- }
- #endif
-
- CComVariant& CComVariant::operator=(int nSrc)
- {
- if (vt != VT_I4)
- {
- InternalClear();
- vt = VT_I4;
- }
- lVal = nSrc;
-
- return *this;
- }
-
- CComVariant& CComVariant::operator=(BYTE nSrc)
- {
- if (vt != VT_UI1)
- {
- InternalClear();
- vt = VT_UI1;
- }
- bVal = nSrc;
- return *this;
- }
-
- CComVariant& CComVariant::operator=(short nSrc)
- {
- if (vt != VT_I2)
- {
- InternalClear();
- vt = VT_I2;
- }
- iVal = nSrc;
- return *this;
- }
-
- CComVariant& CComVariant::operator=(long nSrc)
- {
- if (vt != VT_I4)
- {
- InternalClear();
- vt = VT_I4;
- }
- lVal = nSrc;
- return *this;
- }
-
- CComVariant& CComVariant::operator=(float fltSrc)
- {
- if (vt != VT_R4)
- {
- InternalClear();
- vt = VT_R4;
- }
- fltVal = fltSrc;
- return *this;
- }
-
- CComVariant& CComVariant::operator=(double dblSrc)
- {
- if (vt != VT_R8)
- {
- InternalClear();
- vt = VT_R8;
- }
- dblVal = dblSrc;
- return *this;
- }
-
- CComVariant& CComVariant::operator=(CY cySrc)
- {
- if (vt != VT_CY)
- {
- InternalClear();
- vt = VT_CY;
- }
- #if !defined(BCC32_COMPAT) || defined(_ANONYMOUS_STRUCT)
- cyVal.Hi = cySrc.Hi;
- cyVal.Lo = cySrc.Lo;
- #else
- cyVal.s.Hi = cySrc.s.Hi;
- cyVal.s.Lo = cySrc.s.Lo;
- #endif
- return *this;
- }
-
- CComVariant& CComVariant::operator=(IDispatch* pSrc)
- {
- InternalClear();
- vt = VT_DISPATCH;
- pdispVal = pSrc;
- // Need to AddRef as VariantClear will Release
- if (pdispVal != NULL)
- pdispVal->AddRef();
- return *this;
- }
-
- CComVariant& CComVariant::operator=(IUnknown* pSrc)
- {
- InternalClear();
- vt = VT_UNKNOWN;
- punkVal = pSrc;
-
- // Need to AddRef as VariantClear will Release
- if (punkVal != NULL)
- punkVal->AddRef();
- return *this;
- }
-
- #if _MSC_VER>1020
- bool CComVariant::operator==(const VARIANT& varSrc)
- {
- if (this == &varSrc)
- return true;
-
- // Variants not equal if types don't match
- if (vt != varSrc.vt)
- return false;
-
- // Check type specific values
- switch (vt)
- {
- case VT_EMPTY:
- case VT_NULL:
- return true;
-
- case VT_BOOL:
- return boolVal == varSrc.boolVal;
-
- case VT_UI1:
- return bVal == varSrc.bVal;
-
- case VT_I2:
- return iVal == varSrc.iVal;
-
- case VT_I4:
- return lVal == varSrc.lVal;
-
- case VT_R4:
- return fltVal == varSrc.fltVal;
-
- case VT_R8:
- return dblVal == varSrc.dblVal;
-
- case VT_BSTR:
- return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) &&
- (::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);
-
- case VT_ERROR:
- return scode == varSrc.scode;
-
- case VT_DISPATCH:
- return pdispVal == varSrc.pdispVal;
-
- case VT_UNKNOWN:
- return punkVal == varSrc.punkVal;
-
- default:
- _ASSERTE(false);
- // fall through
- }
-
- return false;
- }
- #else
- BOOL CComVariant::operator==(const VARIANT& varSrc)
- {
- if (this == &varSrc)
- return TRUE;
-
- // Variants not equal if types don't match
- if (vt != varSrc.vt)
- return FALSE;
-
- // Check type specific values
- switch (vt)
- {
- case VT_EMPTY:
- case VT_NULL:
- return TRUE;
-
- case VT_BOOL:
- return boolVal == varSrc.boolVal;
-
- case VT_UI1:
- return bVal == varSrc.bVal;
-
- case VT_I2:
- return iVal == varSrc.iVal;
-
- case VT_I4:
- return lVal == varSrc.lVal;
-
- case VT_R4:
- return fltVal == varSrc.fltVal;
-
- case VT_R8:
- return dblVal == varSrc.dblVal;
-
- case VT_BSTR:
- return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) &&
- (::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);
-
- case VT_ERROR:
- return scode == varSrc.scode;
-
- case VT_DISPATCH:
- return pdispVal == varSrc.pdispVal;
-
- case VT_UNKNOWN:
- return punkVal == varSrc.punkVal;
-
- default:
- _ASSERTE(FALSE);
- // fall through
- }
-
- return FALSE;
- }
- #endif
-
- HRESULT CComVariant::Attach(VARIANT* pSrc)
- {
- // Clear out the variant
- HRESULT hr = Clear();
- if (!FAILED(hr))
- {
- // Copy the contents and give control to CComVariant
- memcpy(this, pSrc, sizeof(VARIANT));
- VariantInit(pSrc);
- hr = S_OK;
- }
- return hr;
- }
-
- HRESULT CComVariant::Detach(VARIANT* pDest)
- {
- // Clear out the variant
- HRESULT hr = ::VariantClear(pDest);
- if (!FAILED(hr))
- {
- // Copy the contents and remove control from CComVariant
- memcpy(pDest, this, sizeof(VARIANT));
- vt = VT_EMPTY;
- hr = S_OK;
- }
- return hr;
- }
-
- HRESULT CComVariant::ChangeType(VARTYPE vtNew, const VARIANT* pSrc)
- {
- VARIANT* pVar = const_cast<VARIANT*>(pSrc);
- // Convert in place if pSrc is NULL
- if (pVar == NULL)
- pVar = this;
- // Do nothing if doing in place convert and vts not different
- return ::VariantChangeType(this, pVar, 0, vtNew);
- }
-
- HRESULT CComVariant::InternalClear()
- {
- HRESULT hr = Clear();
- _ASSERTE(SUCCEEDED(hr));
- if (FAILED(hr))
- {
- vt = VT_ERROR;
- scode = hr;
- }
- return hr;
- }
-
- void CComVariant::InternalCopy(const VARIANT* pSrc)
- {
- HRESULT hr = Copy(pSrc);
- if (FAILED(hr))
- {
- vt = VT_ERROR;
- scode = hr;
- }
- }
-
-
- HRESULT CComVariant::WriteToStream(IStream* pStream)
- {
- HRESULT hr = pStream->Write(&vt, sizeof(VARTYPE), NULL);
- if (FAILED(hr))
- return hr;
-
- int cbWrite = 0;
- switch (vt)
- {
- case VT_UNKNOWN:
- case VT_DISPATCH:
- {
- CComPtr<IPersistStream> spStream;
- if (punkVal != NULL)
- {
- hr = punkVal->QueryInterface(IID_IPersistStream, (void**)&spStream);
- if (FAILED(hr))
- return hr;
- }
- if (spStream != NULL)
- return OleSaveToStream(spStream, pStream);
- else
- return WriteClassStm(pStream, CLSID_NULL);
- }
- case VT_UI1:
- case VT_I1:
- cbWrite = sizeof(BYTE);
- break;
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- cbWrite = sizeof(short);
- break;
- case VT_I4:
- case VT_UI4:
- case VT_R4:
- case VT_INT:
- case VT_UINT:
- case VT_ERROR:
- cbWrite = sizeof(long);
- break;
- case VT_R8:
- case VT_CY:
- case VT_DATE:
- cbWrite = sizeof(double);
- break;
- default:
- break;
- }
- if (cbWrite != 0)
- return pStream->Write((void*) &bVal, cbWrite, NULL);
-
- CComBSTR bstrWrite;
- CComVariant varBSTR;
- if (vt != VT_BSTR)
- {
- hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);
- if (FAILED(hr))
- return hr;
- bstrWrite = varBSTR.bstrVal;
- }
- else
- bstrWrite = bstrVal;
-
- return bstrWrite.WriteToStream(pStream);
- }
-
- HRESULT CComVariant::ReadFromStream(IStream* pStream)
- {
- _ASSERTE(pStream != NULL);
- HRESULT hr;
- hr = VariantClear(this);
- if (FAILED(hr))
- return hr;
- VARTYPE vtRead;
- hr = pStream->Read(&vtRead, sizeof(VARTYPE), NULL);
- if (FAILED(hr))
- return hr;
-
- vt = vtRead;
- int cbRead = 0;
- switch (vtRead)
- {
- case VT_UNKNOWN:
- case VT_DISPATCH:
- {
- punkVal = NULL;
- hr = OleLoadFromStream(pStream,
- (vtRead == VT_UNKNOWN) ? IID_IUnknown : IID_IDispatch,
- (void**)&punkVal);
- if (hr == REGDB_E_CLASSNOTREG)
- hr = S_OK;
- return S_OK;
- }
- case VT_UI1:
- case VT_I1:
- cbRead = sizeof(BYTE);
- break;
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- cbRead = sizeof(short);
- break;
- case VT_I4:
- case VT_UI4:
- case VT_R4:
- case VT_INT:
- case VT_UINT:
- case VT_ERROR:
- cbRead = sizeof(long);
- break;
- case VT_R8:
- case VT_CY:
- case VT_DATE:
- cbRead = sizeof(double);
- break;
- default:
- break;
- }
- if (cbRead != 0)
- return pStream->Read((void*) &bVal, cbRead, NULL);
- CComBSTR bstrRead;
-
- hr = bstrRead.ReadFromStream(pStream);
- if (FAILED(hr))
- return hr;
- vt = VT_BSTR;
- bstrVal = bstrRead.Detach();
- if (vtRead != VT_BSTR)
- hr = ChangeType(vtRead);
- return hr;
- }
-
- #ifdef __ATLCOM_H__
-
- /////////////////////////////////////////////////////////////////////////////
- // CComTypeInfoHolder
-
- void CComTypeInfoHolder::AddRef()
- {
- EnterCriticalSection(&_Module.m_csTypeInfoHolder);
- m_dwRef++;
- LeaveCriticalSection(&_Module.m_csTypeInfoHolder);
- }
-
- void CComTypeInfoHolder::Release()
- {
- EnterCriticalSection(&_Module.m_csTypeInfoHolder);
- if (--m_dwRef == 0)
- {
- if (m_pInfo != NULL)
- m_pInfo->Release();
- m_pInfo = NULL;
- }
- LeaveCriticalSection(&_Module.m_csTypeInfoHolder);
- }
-
- HRESULT CComTypeInfoHolder::GetTI(LCID lcid, ITypeInfo** ppInfo)
- {
- //If this assert occurs then most likely didn't initialize properly
- _ASSERTE(m_plibid != NULL && m_pguid != NULL);
- _ASSERTE(ppInfo != NULL);
- *ppInfo = NULL;
-
- HRESULT hRes = E_FAIL;
- EnterCriticalSection(&_Module.m_csTypeInfoHolder);
- if (m_pInfo == NULL)
- {
- ITypeLib* pTypeLib;
- hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
- if (SUCCEEDED(hRes))
- {
- ITypeInfo* pTypeInfo;
- hRes = pTypeLib->GetTypeInfoOfGuid(*m_pguid, &pTypeInfo);
- if (SUCCEEDED(hRes))
- m_pInfo = pTypeInfo;
- pTypeLib->Release();
- }
- }
- *ppInfo = m_pInfo;
- if (m_pInfo != NULL)
- {
- m_pInfo->AddRef();
- // jmt. Add another to work
- // around remote datamodule problem.
- m_pInfo->AddRef();
- hRes = S_OK;
- }
- LeaveCriticalSection(&_Module.m_csTypeInfoHolder);
- return hRes;
- }
-
- HRESULT CComTypeInfoHolder::GetTypeInfo(UINT /*itinfo*/, LCID lcid,
- ITypeInfo** pptinfo)
- {
- HRESULT hRes = E_POINTER;
- if (pptinfo != NULL)
- hRes = GetTI(lcid, pptinfo);
- return hRes;
- }
-
- HRESULT CComTypeInfoHolder::GetIDsOfNames(REFIID /*riid*/, LPOLESTR* rgszNames,
- UINT cNames, LCID lcid, DISPID* rgdispid)
- {
- ITypeInfo* pInfo;
- HRESULT hRes = GetTI(lcid, &pInfo);
- if (pInfo != NULL)
- {
- hRes = pInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
- pInfo->Release();
- }
- return hRes;
- }
-
- HRESULT CComTypeInfoHolder::Invoke(IDispatch* p, DISPID dispidMember, REFIID /*riid*/,
- LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
- EXCEPINFO* pexcepinfo, UINT* puArgErr)
- {
- SetErrorInfo(0, NULL);
- ITypeInfo* pInfo;
- HRESULT hRes = GetTI(lcid, &pInfo);
- if (pInfo != NULL)
- {
- hRes = pInfo->Invoke(p, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
- pInfo->Release();
- }
- return hRes;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // QI implementation
-
- #ifdef _ATL_DEBUG_QI
- HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr)
- {
- USES_CONVERSION;
- CRegKey key;
- TCHAR szName[100];
- DWORD dwType,dw = sizeof(szName);
-
- LPOLESTR pszGUID = NULL;
- StringFromCLSID(iid, &pszGUID);
- OutputDebugString(pszClassName);
- OutputDebugString(_T(" - "));
-
- // Attempt to find it in the interfaces section
- key.Open(HKEY_CLASSES_ROOT, _T("Interface"));
- if (key.Open(key, OLE2T(pszGUID)) == S_OK)
- {
- *szName = 0;
- RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
- OutputDebugString(szName);
- goto cleanup;
- }
- // Attempt to find it in the clsid section
- key.Open(HKEY_CLASSES_ROOT, _T("CLSID"));
- if (key.Open(key, OLE2T(pszGUID)) == S_OK)
- {
- *szName = 0;
- RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
- OutputDebugString(_T("(CLSID\?\?\?) "));
- OutputDebugString(szName);
- goto cleanup;
- }
- OutputDebugString(OLE2T(pszGUID));
- cleanup:
- if (hr != S_OK)
- OutputDebugString(_T(" - failed"));
- OutputDebugString(_T("\n"));
- CoTaskMemFree(pszGUID);
- return hr;
- }
- #endif
-
- HRESULT WINAPI CComObjectRootBase::_Break(void* /* pv */, REFIID iid, void** /* ppvObject */, DWORD /* dw */)
- {
- iid;
- _ATLDUMPIID(iid, _T("Break due to QI for interface "), S_OK);
- DebugBreak();
- return S_FALSE;
- }
-
- HRESULT WINAPI CComObjectRootBase::_NoInterface(void* /* pv */, REFIID /* iid */, void** /* ppvObject */, DWORD /* dw */)
- {
- return E_NOINTERFACE;
- }
-
- HRESULT WINAPI CComObjectRootBase::_Creator(void* pv, REFIID iid, void** ppvObject, DWORD dw)
- {
- _ATL_CREATORDATA* pcd = (_ATL_CREATORDATA*)dw;
- return pcd->pFunc(pv, iid, ppvObject);
- }
-
- HRESULT WINAPI CComObjectRootBase::_Delegate(void* pv, REFIID iid, void** ppvObject, DWORD dw)
- {
- HRESULT hRes = E_NOINTERFACE;
- IUnknown* p = *(IUnknown**)((DWORD)pv + dw);
- if (p != NULL)
- hRes = p->QueryInterface(iid, ppvObject);
- return hRes;
- }
-
- HRESULT WINAPI CComObjectRootBase::_Chain(void* pv, REFIID iid, void** ppvObject, DWORD dw)
- {
- _ATL_CHAINDATA* pcd = (_ATL_CHAINDATA*)dw;
- void* p = (void*)((DWORD)pv + pcd->dwOffset);
- return InternalQueryInterface(p, pcd->pFunc(), iid, ppvObject);
- }
-
- HRESULT WINAPI CComObjectRootBase::_Cache(void* pv, REFIID iid, void** ppvObject, DWORD dw)
- {
- HRESULT hRes = E_NOINTERFACE;
- _ATL_CACHEDATA* pcd = (_ATL_CACHEDATA*)dw;
- IUnknown** pp = (IUnknown**)((DWORD)pv + pcd->dwOffsetVar);
- if (*pp == NULL)
- hRes = pcd->pFunc(pv, IID_IUnknown, (void**)pp);
- if (*pp != NULL)
- hRes = (*pp)->QueryInterface(iid, ppvObject);
- return hRes;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CComClassFactory
-
- STDMETHODIMP CComClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
- REFIID riid, void** ppvObj)
- {
- _ASSERTE(m_pfnCreateInstance != NULL);
- HRESULT hRes = E_POINTER;
- if (ppvObj != NULL)
- {
- *ppvObj = NULL;
- // can't ask for anything other than IUnknown when aggregating
- _ASSERTE((pUnkOuter == NULL) || InlineIsEqualUnknown(riid));
- if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid))
- hRes = CLASS_E_NOAGGREGATION;
- else
- hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
- }
- return hRes;
- }
-
- STDMETHODIMP CComClassFactory::LockServer(BOOL fLock)
- {
- if (fLock)
- _Module.Lock();
- else
- _Module.Unlock();
- return S_OK;
- }
-
- STDMETHODIMP CComClassFactory2Base::LockServer(BOOL fLock)
- {
- if (fLock)
- _Module.Lock();
- else
- _Module.Unlock();
- return S_OK;
- }
-
- #ifndef _ATL_NO_CONNECTION_POINTS
- /////////////////////////////////////////////////////////////////////////////
- // Connection Points
-
- DWORD CComDynamicUnkArray::Add(IUnknown* pUnk)
- {
- IUnknown** pp = NULL;
- if (m_nSize == 0) // no connections
- {
- m_pUnk = pUnk;
- m_nSize = 1;
- return (DWORD)m_pUnk;
- }
- else if (m_nSize == 1)
- {
- //create array
- pp = (IUnknown**)malloc(sizeof(IUnknown*)*_DEFAULT_VECTORLENGTH);
- if (pp == NULL)
- return 0;
- memset(pp, 0, sizeof(IUnknown*)*_DEFAULT_VECTORLENGTH);
- *pp = m_pUnk;
- m_ppUnk = pp;
- m_nSize = _DEFAULT_VECTORLENGTH;
- }
- for (pp = begin();pp<end();pp++)
- {
- if (*pp == NULL)
- {
- *pp = pUnk;
- return (DWORD)pUnk;
- }
- }
- int nAlloc = m_nSize*2;
- pp = (IUnknown**)realloc(m_ppUnk, sizeof(IUnknown*)*nAlloc);
- if (pp == NULL)
- return 0;
- m_ppUnk = pp;
- memset(&m_ppUnk[m_nSize], 0, sizeof(IUnknown*)*m_nSize);
- m_ppUnk[m_nSize] = pUnk;
- m_nSize = nAlloc;
- return (DWORD)pUnk;
- }
-
- BOOL CComDynamicUnkArray::Remove(DWORD dwCookie)
- {
- IUnknown** pp;
- if (dwCookie == NULL)
- return FALSE;
- if (m_nSize == 0)
- return FALSE;
- if (m_nSize == 1)
- {
- if ((DWORD)m_pUnk == dwCookie)
- {
- m_nSize = 0;
- return TRUE;
- }
- return FALSE;
- }
- for (pp=begin();pp<end();pp++)
- {
- if ((DWORD)*pp == dwCookie)
- {
- *pp = NULL;
- return TRUE;
- }
- }
- return FALSE;
- }
-
- #endif //!_ATL_NO_CONNECTION_POINTS
-
- #endif //__ATLCOM_H__
-
- /////////////////////////////////////////////////////////////////////////////
- // Object Registry Support
-
- static HRESULT WINAPI AtlRegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc)
- {
- CRegKey keyProgID;
- LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID);
- if (lRes == ERROR_SUCCESS)
- {
- keyProgID.SetValue(lpszUserDesc);
- keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);
- return S_OK;
- }
- return HRESULT_FROM_WIN32(lRes);
- }
-
- void CComModule::AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
- {
- pData->m_pThis = pObject;
- pData->m_dwThreadID = ::GetCurrentThreadId();
- ::EnterCriticalSection(&m_csWindowCreate);
- pData->m_pNext = m_pCreateWndList;
- m_pCreateWndList = pData;
- ::LeaveCriticalSection(&m_csWindowCreate);
- }
-
- void* CComModule::ExtractCreateWndData()
- {
- ::EnterCriticalSection(&m_csWindowCreate);
- _AtlCreateWndData* pEntry = m_pCreateWndList;
- if(pEntry == NULL)
- {
- ::LeaveCriticalSection(&m_csWindowCreate);
- return NULL;
- }
-
- DWORD dwThreadID = ::GetCurrentThreadId();
- _AtlCreateWndData* pPrev = NULL;
- while(pEntry != NULL)
- {
- if(pEntry->m_dwThreadID == dwThreadID)
- {
- if(pPrev == NULL)
- m_pCreateWndList = pEntry->m_pNext;
- else
- pPrev->m_pNext = pEntry->m_pNext;
- ::LeaveCriticalSection(&m_csWindowCreate);
- return pEntry->m_pThis;
- }
- pPrev = pEntry;
- pEntry = pEntry->m_pNext;
- }
-
- ::LeaveCriticalSection(&m_csWindowCreate);
- return NULL;
- }
-
- #ifdef _ATL_STATIC_REGISTRY
- // Statically linking to Registry Ponent
- HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
- struct _ATL_REGMAP_ENTRY* pMapEntries)
- {
- USES_CONVERSION;
- CRegObject ro;
- TCHAR szModule[_MAX_PATH];
- GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
- LPOLESTR pszModule = T2OLE(szModule);
- ro.AddReplacement(OLESTR("Module"), pszModule);
- if (NULL != pMapEntries)
- {
- while (NULL != pMapEntries->szKey)
- {
- _ASSERTE(NULL != pMapEntries->szData);
- ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
- pMapEntries++;
- }
- }
-
- LPCOLESTR szType = OLESTR("REGISTRY");
- return (bRegister) ? ro.ResourceRegister(pszModule, nResID, szType) :
- ro.ResourceUnregister(pszModule, nResID, szType);
- }
-
- HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
- struct _ATL_REGMAP_ENTRY* pMapEntries)
- {
- USES_CONVERSION;
- CRegObject ro;
- TCHAR szModule[_MAX_PATH];
- GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
- LPOLESTR pszModule = T2OLE(szModule);
- ro.AddReplacement(OLESTR("Module"), pszModule);
- if (NULL != pMapEntries)
- {
- while (NULL != pMapEntries->szKey)
- {
- _ASSERTE(NULL != pMapEntries->szData);
- ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
- pMapEntries++;
- }
- }
-
- LPCOLESTR szType = OLESTR("REGISTRY");
- LPCOLESTR pszRes = T2COLE(lpszRes);
- return (bRegister) ? ro.ResourceRegisterSz(pszModule, pszRes, szType) :
- ro.ResourceUnregisterSz(pszModule, pszRes, szType);
- }
- #endif // _ATL_STATIC_REGISTRY
-
- HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
- LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister)
- {
- if (bRegister)
- {
- return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, nDescID,
- dwFlags);
- }
- else
- return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
- }
-
- HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
- LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags)
- {
- static const TCHAR szProgID[] = _T("ProgID");
- static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");
- static const TCHAR szLS32[] = _T("LocalServer32");
- static const TCHAR szIPS32[] = _T("InprocServer32");
- static const TCHAR szThreadingModel[] = _T("ThreadingModel");
- static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");
- static const TCHAR szApartment[] = _T("Apartment");
- static const TCHAR szBoth[] = _T("both");
- USES_CONVERSION;
- HRESULT hRes = S_OK;
- TCHAR szDesc[256];
- LoadString(m_hInst, nDescID, szDesc, 256);
- TCHAR szModule[_MAX_PATH];
- GetModuleFileName(m_hInst, szModule, _MAX_PATH);
-
- LPOLESTR lpOleStr;
- StringFromCLSID(clsid, &lpOleStr);
- LPTSTR lpsz = OLE2T(lpOleStr);
-
- hRes = AtlRegisterProgID(lpsz, lpszProgID, szDesc);
- if (hRes == S_OK)
- hRes = AtlRegisterProgID(lpsz, lpszVerIndProgID, szDesc);
- LONG lRes = ERROR_SUCCESS;
- if (hRes == S_OK)
- {
- CRegKey key;
- LONG lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"));
- if (lRes == ERROR_SUCCESS)
- {
- lRes = key.Create(key, lpsz);
- if (lRes == ERROR_SUCCESS)
- {
- key.SetValue(szDesc);
- key.SetKeyValue(szProgID, lpszProgID);
- key.SetKeyValue(szVIProgID, lpszVerIndProgID);
-
- if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE
- key.SetKeyValue(szLS32, szModule);
- else
- {
- key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);
- LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :
- (dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;
- if (lpszModel != NULL)
- key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);
- }
- }
- }
- }
- CoTaskMemFree(lpOleStr);
- if (lRes != ERROR_SUCCESS)
- hRes = HRESULT_FROM_WIN32(lRes);
- return hRes;
- }
-
- HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
- LPCTSTR lpszVerIndProgID)
- {
- USES_CONVERSION;
- CRegKey key;
-
- key.Attach(HKEY_CLASSES_ROOT);
- if (lpszProgID != NULL && lstrcmpi(lpszProgID, _T("")))
- key.RecurseDeleteKey(lpszProgID);
- if (lpszVerIndProgID != NULL && lstrcmpi(lpszVerIndProgID, _T("")))
- key.RecurseDeleteKey(lpszVerIndProgID);
- LPOLESTR lpOleStr;
- StringFromCLSID(clsid, &lpOleStr);
- LPTSTR lpsz = OLE2T(lpOleStr);
- if (key.Open(key, _T("CLSID")) == ERROR_SUCCESS)
- key.RecurseDeleteKey(lpsz);
- CoTaskMemFree(lpOleStr);
- return S_OK;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CRegKey
-
- LONG CRegKey::Close()
- {
- LONG lRes = ERROR_SUCCESS;
- if (m_hKey != NULL)
- {
- lRes = RegCloseKey(m_hKey);
- m_hKey = NULL;
- }
- return lRes;
- }
-
- LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
- LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition)
- {
- _ASSERTE(hKeyParent != NULL);
- DWORD dw;
- HKEY hKey = NULL;
- LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,
- lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);
- if (lpdwDisposition != NULL)
- *lpdwDisposition = dw;
- if (lRes == ERROR_SUCCESS)
- {
- lRes = Close();
- m_hKey = hKey;
- }
- return lRes;
- }
-
- LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired)
- {
- _ASSERTE(hKeyParent != NULL);
- HKEY hKey = NULL;
- LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
- if (lRes == ERROR_SUCCESS)
- {
- lRes = Close();
- _ASSERTE(lRes == ERROR_SUCCESS);
- m_hKey = hKey;
- }
- return lRes;
- }
-
- LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
- {
- DWORD dwType = NULL;
- DWORD dwCount = sizeof(DWORD);
- LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
- (LPBYTE)&dwValue, &dwCount);
- _ASSERTE((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));
- _ASSERTE((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));
- return lRes;
- }
-
- LONG CRegKey::QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount)
- {
- _ASSERTE(pdwCount != NULL);
- DWORD dwType = NULL;
- LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
- (LPBYTE)szValue, pdwCount);
- _ASSERTE((lRes!=ERROR_SUCCESS) || (dwType == REG_SZ) ||
- (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ));
- return lRes;
- }
-
- LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
- {
- _ASSERTE(lpszValue != NULL);
- CRegKey key;
- LONG lRes = key.Create(hKeyParent, lpszKeyName);
- if (lRes == ERROR_SUCCESS)
- lRes = key.SetValue(lpszValue, lpszValueName);
- return lRes;
- }
-
- LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
- {
- _ASSERTE(lpszValue != NULL);
- CRegKey key;
- LONG lRes = key.Create(m_hKey, lpszKeyName);
- if (lRes == ERROR_SUCCESS)
- lRes = key.SetValue(lpszValue, lpszValueName);
- return lRes;
- }
-
- LONG CRegKey::SetValue(DWORD dwValue, LPCTSTR lpszValueName)
- {
- _ASSERTE(m_hKey != NULL);
- return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_DWORD,
- (BYTE * const)&dwValue, sizeof(DWORD));
- }
-
- HRESULT CRegKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName)
- {
- _ASSERTE(lpszValue != NULL);
- _ASSERTE(m_hKey != NULL);
- return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_SZ,
- (BYTE * const)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));
- }
-
- //RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
- //specified key has subkeys
- LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey)
- {
- CRegKey key;
- LONG lRes = key.Open(m_hKey, lpszKey);
- if (lRes != ERROR_SUCCESS)
- return lRes;
- FILETIME time;
- TCHAR szBuffer[256];
- DWORD dwSize = 256;
- while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,
- &time)==ERROR_SUCCESS)
- {
- lRes = key.RecurseDeleteKey(szBuffer);
- if (lRes != ERROR_SUCCESS)
- return lRes;
- dwSize = 256;
- }
- key.Close();
- return DeleteSubKey(lpszKey);
- }
-
- #ifdef __ATLCOM_H__
- #ifndef _ATL_NO_SECURITY
-
- CSecurityDescriptor::CSecurityDescriptor()
- {
- m_pSD = NULL;
- m_pOwner = NULL;
- m_pGroup = NULL;
- m_pDACL = NULL;
- m_pSACL= NULL;
- }
-
- CSecurityDescriptor::~CSecurityDescriptor()
- {
- if (m_pSD)
- delete m_pSD;
- if (m_pOwner)
- free(m_pOwner);
- if (m_pGroup)
- free(m_pGroup);
- if (m_pDACL)
- free(m_pDACL);
- if (m_pSACL)
- free(m_pSACL);
- }
-
- HRESULT CSecurityDescriptor::Initialize()
- {
- if (m_pSD)
- {
- delete m_pSD;
- m_pSD = NULL;
- }
- if (m_pOwner)
- {
- free(m_pOwner);
- m_pOwner = NULL;
- }
- if (m_pGroup)
- {
- free(m_pGroup);
- m_pGroup = NULL;
- }
- if (m_pDACL)
- {
- free(m_pDACL);
- m_pDACL = NULL;
- }
- if (m_pSACL)
- {
- free(m_pSACL);
- m_pSACL = NULL;
- }
-
- ATLTRY(m_pSD = new SECURITY_DESCRIPTOR);
- if (!m_pSD)
- return E_OUTOFMEMORY;
- if (!InitializeSecurityDescriptor(m_pSD, SECURITY_DESCRIPTOR_REVISION))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- delete m_pSD;
- m_pSD = NULL;
- _ASSERTE(FALSE);
- return hr;
- }
- // Set the DACL to allow EVERYONE
- SetSecurityDescriptorDacl(m_pSD, TRUE, NULL, FALSE);
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::InitializeFromProcessToken(BOOL bDefaulted)
- {
- PSID pUserSid;
- PSID pGroupSid;
- HRESULT hr;
-
- Initialize();
- hr = GetProcessSids(&pUserSid, &pGroupSid);
- if (FAILED(hr))
- return hr;
- hr = SetOwner(pUserSid, bDefaulted);
- if (FAILED(hr))
- return hr;
- hr = SetGroup(pGroupSid, bDefaulted);
- if (FAILED(hr))
- return hr;
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::InitializeFromThreadToken(BOOL bDefaulted, BOOL bRevertToProcessToken)
- {
- PSID pUserSid;
- PSID pGroupSid;
- HRESULT hr;
-
- Initialize();
- hr = GetThreadSids(&pUserSid, &pGroupSid);
- if (HRESULT_CODE(hr) == ERROR_NO_TOKEN && bRevertToProcessToken)
- hr = GetProcessSids(&pUserSid, &pGroupSid);
- if (FAILED(hr))
- return hr;
- hr = SetOwner(pUserSid, bDefaulted);
- if (FAILED(hr))
- return hr;
- hr = SetGroup(pGroupSid, bDefaulted);
- if (FAILED(hr))
- return hr;
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::SetOwner(PSID pOwnerSid, BOOL bDefaulted)
- {
- _ASSERTE(m_pSD);
-
- // Mark the SD as having no owner
- if (!SetSecurityDescriptorOwner(m_pSD, NULL, bDefaulted))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
-
- if (m_pOwner)
- {
- free(m_pOwner);
- m_pOwner = NULL;
- }
-
- // If they asked for no owner don't do the copy
- if (pOwnerSid == NULL)
- return S_OK;
-
- // Make a copy of the Sid for the return value
- DWORD dwSize = GetLengthSid(pOwnerSid);
-
- m_pOwner = (PSID) malloc(dwSize);
- if (!m_pOwner)
- {
- // Insufficient memory to allocate Sid
- _ASSERTE(FALSE);
- return E_OUTOFMEMORY;
- }
- if (!CopySid(dwSize, m_pOwner, pOwnerSid))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- free(m_pOwner);
- m_pOwner = NULL;
- return hr;
- }
-
- _ASSERTE(IsValidSid(m_pOwner));
-
- if (!SetSecurityDescriptorOwner(m_pSD, m_pOwner, bDefaulted))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- free(m_pOwner);
- m_pOwner = NULL;
- return hr;
- }
-
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::SetGroup(PSID pGroupSid, BOOL bDefaulted)
- {
- _ASSERTE(m_pSD);
-
- // Mark the SD as having no Group
- if (!SetSecurityDescriptorGroup(m_pSD, NULL, bDefaulted))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
-
- if (m_pGroup)
- {
- free(m_pGroup);
- m_pGroup = NULL;
- }
-
- // If they asked for no Group don't do the copy
- if (pGroupSid == NULL)
- return S_OK;
-
- // Make a copy of the Sid for the return value
- DWORD dwSize = GetLengthSid(pGroupSid);
-
- m_pGroup = (PSID) malloc(dwSize);
- if (!m_pGroup)
- {
- // Insufficient memory to allocate Sid
- _ASSERTE(FALSE);
- return E_OUTOFMEMORY;
- }
- if (!CopySid(dwSize, m_pGroup, pGroupSid))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- free(m_pGroup);
- m_pGroup = NULL;
- return hr;
- }
-
- _ASSERTE(IsValidSid(m_pGroup));
-
- if (!SetSecurityDescriptorGroup(m_pSD, m_pGroup, bDefaulted))
- {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- free(m_pGroup);
- m_pGroup = NULL;
- return hr;
- }
-
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::Allow(LPCTSTR pszPrincipal, DWORD dwAccessMask)
- {
- HRESULT hr = AddAccessAllowedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
- if (SUCCEEDED(hr))
- SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
- return hr;
- }
-
- HRESULT CSecurityDescriptor::Deny(LPCTSTR pszPrincipal, DWORD dwAccessMask)
- {
- HRESULT hr = AddAccessDeniedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
- if (SUCCEEDED(hr))
- SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
- return hr;
- }
-
- HRESULT CSecurityDescriptor::Revoke(LPCTSTR pszPrincipal)
- {
- HRESULT hr = RemovePrincipalFromACL(m_pDACL, pszPrincipal);
- if (SUCCEEDED(hr))
- SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
- return hr;
- }
-
- HRESULT CSecurityDescriptor::GetProcessSids(PSID* ppUserSid, PSID* ppGroupSid)
- {
- BOOL bRes;
- HRESULT hr;
- HANDLE hToken = NULL;
- if (ppUserSid)
- *ppUserSid = NULL;
- if (ppGroupSid)
- *ppGroupSid = NULL;
- bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
- if (!bRes)
- {
- // Couldn't open process token
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
- hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
- return hr;
- }
-
- HRESULT CSecurityDescriptor::GetThreadSids(PSID* ppUserSid, PSID* ppGroupSid, BOOL bOpenAsSelf)
- {
- BOOL bRes;
- HRESULT hr;
- HANDLE hToken = NULL;
- if (ppUserSid)
- *ppUserSid = NULL;
- if (ppGroupSid)
- *ppGroupSid = NULL;
- bRes = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, bOpenAsSelf, &hToken);
- if (!bRes)
- {
- // Couldn't open thread token
- hr = HRESULT_FROM_WIN32(GetLastError());
- return hr;
- }
- hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
- return hr;
- }
-
-
- HRESULT CSecurityDescriptor::GetTokenSids(HANDLE hToken, PSID* ppUserSid, PSID* ppGroupSid)
- {
- DWORD dwSize;
- HRESULT hr;
- PTOKEN_USER ptkUser = NULL;
- PTOKEN_PRIMARY_GROUP ptkGroup = NULL;
-
- if (ppUserSid)
- *ppUserSid = NULL;
- if (ppGroupSid)
- *ppGroupSid = NULL;
-
- if (ppUserSid)
- {
- // Get length required for TokenUser by specifying buffer length of 0
- GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
- hr = GetLastError();
- if (hr != ERROR_INSUFFICIENT_BUFFER)
- {
- // Expected ERROR_INSUFFICIENT_BUFFER
- _ASSERTE(FALSE);
- hr = HRESULT_FROM_WIN32(hr);
- goto failed;
- }
-
- ptkUser = (TOKEN_USER*) malloc(dwSize);
- if (!ptkUser)
- {
- // Insufficient memory to allocate TOKEN_USER
- _ASSERTE(FALSE);
- hr = E_OUTOFMEMORY;
- goto failed;
- }
- // Get Sid of process token.
- if (!GetTokenInformation(hToken, TokenUser, ptkUser, dwSize, &dwSize))
- {
- // Couldn't get user info
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- goto failed;
- }
-
- // Make a copy of the Sid for the return value
- dwSize = GetLengthSid(ptkUser->User.Sid);
-
- PSID pSid = (PSID) malloc(dwSize);
- if (!pSid)
- {
- // Insufficient memory to allocate Sid
- _ASSERTE(FALSE);
- hr = E_OUTOFMEMORY;
- goto failed;
- }
- if (!CopySid(dwSize, pSid, ptkUser->User.Sid))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- goto failed;
- }
-
- _ASSERTE(IsValidSid(pSid));
- *ppUserSid = pSid;
- free(ptkUser);
- }
- if (ppGroupSid)
- {
- // Get length required for TokenPrimaryGroup by specifying buffer length of 0
- GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwSize);
- hr = GetLastError();
- if (hr != ERROR_INSUFFICIENT_BUFFER)
- {
- // Expected ERROR_INSUFFICIENT_BUFFER
- _ASSERTE(FALSE);
- hr = HRESULT_FROM_WIN32(hr);
- goto failed;
- }
-
- ptkGroup = (TOKEN_PRIMARY_GROUP*) malloc(dwSize);
- if (!ptkGroup)
- {
- // Insufficient memory to allocate TOKEN_USER
- _ASSERTE(FALSE);
- hr = E_OUTOFMEMORY;
- goto failed;
- }
- // Get Sid of process token.
- if (!GetTokenInformation(hToken, TokenPrimaryGroup, ptkGroup, dwSize, &dwSize))
- {
- // Couldn't get user info
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- goto failed;
- }
-
- // Make a copy of the Sid for the return value
- dwSize = GetLengthSid(ptkGroup->PrimaryGroup);
-
- PSID pSid = (PSID) malloc(dwSize);
- if (!pSid)
- {
- // Insufficient memory to allocate Sid
- _ASSERTE(FALSE);
- hr = E_OUTOFMEMORY;
- goto failed;
- }
- if (!CopySid(dwSize, pSid, ptkGroup->PrimaryGroup))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- goto failed;
- }
-
- _ASSERTE(IsValidSid(pSid));
-
- *ppGroupSid = pSid;
- free(ptkGroup);
- }
-
- return S_OK;
-
- failed:
- if (ptkUser)
- free(ptkUser);
- if (ptkGroup)
- free (ptkGroup);
- return hr;
- }
-
-
- HRESULT CSecurityDescriptor::GetCurrentUserSID(PSID *ppSid)
- {
- HANDLE tkHandle;
-
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkHandle))
- {
- TOKEN_USER *tkUser;
- DWORD tkSize;
- DWORD sidLength;
-
- // Call to get size information for alloc
- GetTokenInformation(tkHandle, TokenUser, NULL, 0, &tkSize);
- tkUser = (TOKEN_USER *) malloc(tkSize);
-
- // Now make the real call
- if (GetTokenInformation(tkHandle, TokenUser, tkUser, tkSize, &tkSize))
- {
- sidLength = GetLengthSid(tkUser->User.Sid);
- *ppSid = (PSID) malloc(sidLength);
-
- memcpy(*ppSid, tkUser->User.Sid, sidLength);
- CloseHandle(tkHandle);
-
- free(tkUser);
- return S_OK;
- }
- else
- {
- free(tkUser);
- return HRESULT_FROM_WIN32(GetLastError());
- }
- }
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
-
- HRESULT CSecurityDescriptor::GetPrincipalSID(LPCTSTR pszPrincipal, PSID *ppSid)
- {
- HRESULT hr;
- LPTSTR pszRefDomain = NULL;
- DWORD dwDomainSize = 0;
- DWORD dwSidSize = 0;
- SID_NAME_USE snu;
-
- // Call to get size info for alloc
- LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu);
-
- hr = GetLastError();
- if (hr != ERROR_INSUFFICIENT_BUFFER)
- return HRESULT_FROM_WIN32(hr);
-
- ATLTRY(pszRefDomain = new TCHAR[dwDomainSize]);
- if (pszRefDomain == NULL)
- return E_OUTOFMEMORY;
-
- *ppSid = (PSID) malloc(dwSidSize);
- if (*ppSid != NULL)
- {
- if (!LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu))
- {
- free(*ppSid);
- *ppSid = NULL;
- delete[] pszRefDomain;
- return HRESULT_FROM_WIN32(GetLastError());
- }
- delete[] pszRefDomain;
- return S_OK;
- }
- delete[] pszRefDomain;
- return E_OUTOFMEMORY;
- }
-
-
- HRESULT CSecurityDescriptor::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD)
- {
- PACL pDACL = NULL;
- PACL pSACL = NULL;
- BOOL bDACLPresent, bSACLPresent;
- BOOL bDefaulted;
- PACL m_pDACL = NULL;
- ACCESS_ALLOWED_ACE* pACE;
- HRESULT hr;
- PSID pUserSid;
- PSID pGroupSid;
-
- hr = Initialize();
- if(FAILED(hr))
- return hr;
-
- // get the existing DACL.
- if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted))
- goto failed;
-
- if (bDACLPresent)
- {
- if (pDACL)
- {
- // allocate new DACL.
- m_pDACL = (PACL) malloc(pDACL->AclSize);
- if (!m_pDACL)
- goto failed;
-
- // initialize the DACL
- if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION))
- goto failed;
-
- // copy the ACES
- for (int i = 0; i < pDACL->AceCount; i++)
- {
- if (!GetAce(pDACL, i, (void **)&pACE))
- goto failed;
-
- if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
- goto failed;
- }
-
- if (!IsValidAcl(m_pDACL))
- goto failed;
- }
-
- // set the DACL
- if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted))
- goto failed;
- }
-
- // get the existing SACL.
- if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted))
- goto failed;
-
- if (bSACLPresent)
- {
- if (pSACL)
- {
- // allocate new SACL.
- m_pSACL = (PACL) malloc(pSACL->AclSize);
- if (!m_pSACL)
- goto failed;
-
- // initialize the SACL
- if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION))
- goto failed;
-
- // copy the ACES
- for (int i = 0; i < pSACL->AceCount; i++)
- {
- if (!GetAce(pSACL, i, (void **)&pACE))
- goto failed;
-
- if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
- goto failed;
- }
-
- if (!IsValidAcl(m_pSACL))
- goto failed;
- }
-
- // set the SACL
- if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted))
- goto failed;
- }
-
- if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted))
- goto failed;
-
- if (FAILED(SetOwner(pUserSid, bDefaulted)))
- goto failed;
-
- if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted))
- goto failed;
-
- if (FAILED(SetGroup(pGroupSid, bDefaulted)))
- goto failed;
-
- if (!IsValidSecurityDescriptor(m_pSD))
- goto failed;
-
- return hr;
-
- failed:
- if (m_pDACL)
- free(m_pDACL);
- if (m_pSD)
- free(m_pSD);
- return E_UNEXPECTED;
- }
-
- HRESULT CSecurityDescriptor::AttachObject(HANDLE hObject)
- {
- HRESULT hr;
- DWORD dwSize = 0;
- PSECURITY_DESCRIPTOR pSD = NULL;
-
- GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION, pSD, 0, &dwSize);
-
- hr = GetLastError();
- if (hr != ERROR_INSUFFICIENT_BUFFER)
- return HRESULT_FROM_WIN32(hr);
-
- pSD = (PSECURITY_DESCRIPTOR) malloc(dwSize);
-
- if (!GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION, pSD, dwSize, &dwSize))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- free(pSD);
- return hr;
- }
-
- hr = Attach(pSD);
- free(pSD);
- return hr;
- }
-
-
- HRESULT CSecurityDescriptor::CopyACL(PACL pDest, PACL pSrc)
- {
- ACL_SIZE_INFORMATION aclSizeInfo;
- LPVOID pAce;
- ACE_HEADER *aceHeader;
-
- if (pSrc == NULL)
- return S_OK;
-
- if (!GetAclInformation(pSrc, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
- return HRESULT_FROM_WIN32(GetLastError());
-
- // Copy all of the ACEs to the new ACL
- for (UINT i = 0; i < aclSizeInfo.AceCount; i++)
- {
- if (!GetAce(pSrc, i, &pAce))
- return HRESULT_FROM_WIN32(GetLastError());
-
- aceHeader = (ACE_HEADER *) pAce;
-
- if (!AddAce(pDest, ACL_REVISION, 0xffffffff, pAce, aceHeader->AceSize))
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- return S_OK;
- }
-
- HRESULT CSecurityDescriptor::AddAccessDeniedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
- {
- ACL_SIZE_INFORMATION aclSizeInfo;
- int aclSize;
- DWORD returnValue;
- PSID principalSID;
- PACL oldACL, newACL;
-
- oldACL = *ppAcl;
-
- returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
- if (FAILED(returnValue))
- return returnValue;
-
- aclSizeInfo.AclBytesInUse = 0;
- if (*ppAcl != NULL)
- GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
-
- aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
-
- ATLTRY(newACL = (PACL) new BYTE[aclSize]);
-
- if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
- {
- free(principalSID);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- if (!AddAccessDeniedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
- {
- free(principalSID);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- returnValue = CopyACL(newACL, oldACL);
- if (FAILED(returnValue))
- {
- free(principalSID);
- return returnValue;
- }
-
- *ppAcl = newACL;
-
- if (oldACL != NULL)
- free(oldACL);
- free(principalSID);
- return S_OK;
- }
-
-
- HRESULT CSecurityDescriptor::AddAccessAllowedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
- {
- ACL_SIZE_INFORMATION aclSizeInfo;
- int aclSize;
- DWORD returnValue;
- PSID principalSID;
- PACL oldACL, newACL;
-
- oldACL = *ppAcl;
-
- returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
- if (FAILED(returnValue))
- return returnValue;
-
- aclSizeInfo.AclBytesInUse = 0;
- if (*ppAcl != NULL)
- GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
-
- aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
-
- ATLTRY(newACL = (PACL) new BYTE[aclSize]);
-
- if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
- {
- free(principalSID);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- returnValue = CopyACL(newACL, oldACL);
- if (FAILED(returnValue))
- {
- free(principalSID);
- return returnValue;
- }
-
- if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
- {
- free(principalSID);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- *ppAcl = newACL;
-
- if (oldACL != NULL)
- free(oldACL);
- free(principalSID);
- return S_OK;
- }
-
-
- HRESULT CSecurityDescriptor::RemovePrincipalFromACL(PACL pAcl, LPCTSTR pszPrincipal)
- {
- ACL_SIZE_INFORMATION aclSizeInfo;
- ULONG i;
- LPVOID ace;
- ACCESS_ALLOWED_ACE *accessAllowedAce;
- ACCESS_DENIED_ACE *accessDeniedAce;
- SYSTEM_AUDIT_ACE *systemAuditAce;
- PSID principalSID;
- DWORD returnValue;
- ACE_HEADER *aceHeader;
-
- returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
- if (FAILED(returnValue))
- return returnValue;
-
- GetAclInformation(pAcl, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
-
- for (i = 0; i < aclSizeInfo.AceCount; i++)
- {
- if (!GetAce(pAcl, i, &ace))
- {
- free(principalSID);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- aceHeader = (ACE_HEADER *) ace;
-
- if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
- {
- accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
-
- if (EqualSid(principalSID, (PSID) &accessAllowedAce->SidStart))
- {
- DeleteAce(pAcl, i);
- free(principalSID);
- return S_OK;
- }
- } else
-
- if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
- {
- accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
-
- if (EqualSid(principalSID, (PSID) &accessDeniedAce->SidStart))
- {
- DeleteAce(pAcl, i);
- free(principalSID);
- return S_OK;
- }
- } else
-
- if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
- {
- systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
-
- if (EqualSid(principalSID, (PSID) &systemAuditAce->SidStart))
- {
- DeleteAce(pAcl, i);
- free(principalSID);
- return S_OK;
- }
- }
- }
- free(principalSID);
- return S_OK;
- }
-
-
- HRESULT CSecurityDescriptor::SetPrivilege(LPCTSTR privilege, BOOL bEnable, HANDLE hToken)
- {
- HRESULT hr;
- TOKEN_PRIVILEGES tpPrevious;
- TOKEN_PRIVILEGES tp;
- DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
- LUID luid;
-
- // if no token specified open process token
- if (hToken == 0)
- {
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
- }
-
- if (!LookupPrivilegeValue(NULL, privilege, &luid ))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
-
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = 0;
-
- if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
-
- tpPrevious.PrivilegeCount = 1;
- tpPrevious.Privileges[0].Luid = luid;
-
- if (bEnable)
- tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
- else
- tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
-
- if (!AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FALSE);
- return hr;
- }
- return S_OK;
- }
-
- #endif //_ATL_NO_SECURITY
- #endif //__ATLCOM_H__
-
- #ifdef _DEBUG
-
- void _cdecl AtlTrace(LPCTSTR lpszFormat, ...)
- {
- va_list args;
- va_start(args, lpszFormat);
-
- int nBuf;
- TCHAR szBuffer[512];
-
- nBuf = _vstprintf(szBuffer, lpszFormat, args);
- _ASSERTE(nBuf < sizeof(szBuffer));
-
- OutputDebugString(szBuffer);
- va_end(args);
- }
- #endif
-
- #ifndef ATL_NO_NAMESPACE
- }; //namespace ATL
- #endif
-
- ///////////////////////////////////////////////////////////////////////////////
- //All Global stuff goes below this line
- ///////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Minimize CRT
- // Specify DllMain as EntryPoint
- // Turn off exception handling
- // Define _ATL_MIN_CRT
-
- #ifdef _ATL_MIN_CRT
- /////////////////////////////////////////////////////////////////////////////
- // Startup Code
-
- #if defined(_WINDLL) || defined(_USRDLL)
-
- // Declare DllMain
- extern "C" BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved);
-
- extern "C" BOOL WINAPI _DllMainCRTStartup(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved)
- {
- return DllMain(hDllHandle, dwReason, lpReserved);
- }
-
- #else
-
- // wWinMain is not defined in winbase.h.
- extern "C" int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd);
-
- #define SPACECHAR _T(' ')
- #define DQUOTECHAR _T('\"')
-
-
- #ifdef _UNICODE
- extern "C" void wWinMainCRTStartup()
- #else // _UNICODE
- extern "C" void WinMainCRTStartup()
- #endif // _UNICODE
- {
- LPTSTR lpszCommandLine = ::GetCommandLine();
- if(lpszCommandLine == NULL)
- ::ExitProcess((UINT)-1);
-
- // Skip past program name (first token in command line).
- // Check for and handle quoted program name.
- if(*lpszCommandLine == DQUOTECHAR)
- {
- // Scan, and skip over, subsequent characters until
- // another double-quote or a null is encountered.
- do
- {
- lpszCommandLine = ::CharNext(lpszCommandLine);
- }
- while((*lpszCommandLine != DQUOTECHAR) && (*lpszCommandLine != _T('\0')));
-
- // If we stopped on a double-quote (usual case), skip over it.
- if(*lpszCommandLine == DQUOTECHAR)
- lpszCommandLine = ::CharNext(lpszCommandLine);
- }
- else
- {
- while(*lpszCommandLine > SPACECHAR)
- lpszCommandLine = ::CharNext(lpszCommandLine);
- }
-
- // Skip past any white space preceeding the second token.
- while(*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
- lpszCommandLine = ::CharNext(lpszCommandLine);
-
- STARTUPINFO StartupInfo;
- StartupInfo.dwFlags = 0;
- ::GetStartupInfo(&StartupInfo);
-
- int nRet = _tWinMain(::GetModuleHandle(NULL), NULL, lpszCommandLine,
- (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ?
- StartupInfo.wShowWindow : SW_SHOWDEFAULT);
-
- ::ExitProcess((UINT)nRet);
- }
-
- #endif // defined(_WINDLL) | defined(_USRDLL)
-
- /////////////////////////////////////////////////////////////////////////////
- // Heap Allocation
-
- #ifndef _DEBUG
-
- #ifndef _MERGE_PROXYSTUB
- //rpcproxy.h does the same thing as this
- int __cdecl _purecall()
- {
- DebugBreak();
- return 0;
- }
- #endif
-
- extern "C" const int _fltused = 0;
-
- void* __cdecl malloc(size_t n)
- {
- if (_Module.m_hHeap == NULL)
- {
- _Module.m_hHeap = HeapCreate(0, 0, 0);
- if (_Module.m_hHeap == NULL)
- return NULL;
- }
- _ASSERTE(_Module.m_hHeap != NULL);
-
- #ifdef _MALLOC_ZEROINIT
- return HeapAlloc(_Module.m_hHeap, HEAP_ZERO_MEMORY, n);
- #else
- return HeapAlloc(_Module.m_hHeap, 0, n);
- #endif
- }
-
- void* __cdecl calloc(size_t n, size_t s)
- {
- return malloc(n * s);
- }
-
- void* __cdecl realloc(void* p, size_t n)
- {
- _ASSERTE(_Module.m_hHeap != NULL);
- #ifdef _MALLOC_ZEROINIT
- return (p == NULL) ? malloc(n) : HeapReAlloc(_Module.m_hHeap, HEAP_ZERO_MEMORY, p, n);
- #else
- return (p == NULL) ? malloc(n) : HeapReAlloc(_Module.m_hHeap, 0, p, n);
- #endif
- }
-
- void __cdecl free(void* p)
- {
- _ASSERTE(_Module.m_hHeap != NULL);
- HeapFree(_Module.m_hHeap, 0, p);
- }
-
- void* __cdecl operator new(size_t n)
- {
- return malloc(n);
- }
-
- void __cdecl operator delete(void* p)
- {
- free(p);
- }
-
- #endif //_DEBUG
-
- #endif //_ATL_MIN_CRT
-
- #ifndef _ATL_DLL
-
- #ifndef ATL_NO_NAMESPACE
- #ifndef _ATL_DLL_IMPL
- namespace ATL
- {
- #endif
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // statics
-
- static UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName)
- {
- _ASSERTE(lpszPathName != NULL);
-
- // always capture the complete file name including extension (if present)
- LPCOLESTR lpszTemp = lpszPathName;
- for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; )
- {
- LPCOLESTR lp = CharNextO(lpsz);
- // remember last directory/drive separator
- if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
- lpszTemp = lp;
- lpsz = lp;
- }
-
- return lpszTemp-lpszPathName;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // QI support
-
- ATLAPI AtlInternalQueryInterface(void* pThis,
- const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
- {
- _ASSERTE(pThis != NULL);
- // First entry in the com map should be a simple map entry
- _ASSERTE(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
- if (ppvObject == NULL)
- return E_POINTER;
- *ppvObject = NULL;
- if (InlineIsEqualUnknown(iid)) // use first interface
- {
- IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
- pUnk->AddRef();
- *ppvObject = pUnk;
- return S_OK;
- }
- while (pEntries->pFunc != NULL)
- {
- BOOL bBlind = (pEntries->piid == NULL);
- if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
- {
- if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
- {
- _ASSERTE(!bBlind);
- IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
- pUnk->AddRef();
- *ppvObject = pUnk;
- return S_OK;
- }
- else //actual function call
- {
- HRESULT hRes = pEntries->pFunc(pThis,
- iid, ppvObject, pEntries->dw);
- if (hRes == S_OK || (!bBlind && FAILED(hRes)))
- return hRes;
- }
- }
- pEntries++;
- }
- return E_NOINTERFACE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Smart Pointer helpers
-
- ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
- {
- if (lp != NULL)
- lp->AddRef();
- if (*pp)
- (*pp)->Release();
- *pp = lp;
- return lp;
- }
-
- ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
- {
- IUnknown* pTemp = *pp;
- lp->QueryInterface(riid, (void**)pp);
- if (pTemp)
- pTemp->Release();
- return *pp;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Inproc Marshaling helpers
-
- ATLAPI AtlFreeMarshalStream(IStream* pStream)
- {
- if (pStream != NULL)
- {
- CoReleaseMarshalData(pStream);
- pStream->Release();
- }
- return S_OK;
- }
-
- ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream)
- {
- HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
- if (SUCCEEDED(hRes))
- {
- hRes = CoMarshalInterface(*ppStream, iid,
- pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
- if (FAILED(hRes))
- {
- (*ppStream)->Release();
- *ppStream = NULL;
- }
- }
- return hRes;
- }
-
- ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk)
- {
- *ppUnk = NULL;
- HRESULT hRes = E_INVALIDARG;
- if (pStream != NULL)
- {
- LARGE_INTEGER l;
- l.QuadPart = 0;
- pStream->Seek(l, STREAM_SEEK_SET, NULL);
- hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);
- }
- return hRes;
- }
-
- ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent)
- {
- DWORD dwRet;
- MSG msg;
-
- while(1)
- {
- dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);
-
- if (dwRet == WAIT_OBJECT_0)
- return TRUE; // The event was signaled
-
- if (dwRet != WAIT_OBJECT_0 + 1)
- break; // Something else happened
-
- // There is one or more window message available. Dispatch them
- while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
- return TRUE; // Event is now signaled.
- }
- }
- return FALSE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Connection Point Helpers
-
- ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
- {
- CComPtr<IConnectionPointContainer> pCPC;
- CComPtr<IConnectionPoint> pCP;
- HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
- if (SUCCEEDED(hRes))
- hRes = pCPC->FindConnectionPoint(iid, &pCP);
- if (SUCCEEDED(hRes))
- hRes = pCP->Advise(pUnk, pdw);
- return hRes;
- }
-
- ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
- {
- CComPtr<IConnectionPointContainer> pCPC;
- CComPtr<IConnectionPoint> pCP;
- HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
- if (SUCCEEDED(hRes))
- hRes = pCPC->FindConnectionPoint(iid, &pCP);
- if (SUCCEEDED(hRes))
- hRes = pCP->Unadvise(dw);
- return hRes;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // IDispatch Error handling
-
- ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,
- LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst)
- {
- USES_CONVERSION;
- TCHAR szDesc[1024];
- szDesc[0] = NULL;
- // For a valid HRESULT the id should be in the range [0x0200, 0xffff]
- if (HIWORD(lpszDesc) == 0) //id
- {
- UINT nID = LOWORD((DWORD)lpszDesc);
- _ASSERTE((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);
- if (LoadString(hInst, nID, szDesc, 1024) == 0)
- {
- _ASSERTE(FALSE);
- lstrcpy(szDesc, _T("Unknown Error"));
- }
- lpszDesc = T2OLE(szDesc);
- if (hRes == 0)
- hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);
- }
-
- CComPtr<ICreateErrorInfo> pICEI;
- if (SUCCEEDED(CreateErrorInfo(&pICEI)))
- {
- CComPtr<IErrorInfo> pErrorInfo;
- pICEI->SetGUID(iid);
- LPOLESTR lpsz;
- ProgIDFromCLSID(clsid, &lpsz);
- if (lpsz != NULL)
- pICEI->SetSource(lpsz);
- if (dwHelpID != 0 && lpszHelpFile != NULL)
- {
- pICEI->SetHelpContext(dwHelpID);
- pICEI->SetHelpFile(const_cast<LPOLESTR>(lpszHelpFile));
- }
- CoTaskMemFree(lpsz);
- pICEI->SetDescription((LPOLESTR)lpszDesc);
- if (SUCCEEDED(pICEI->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo)))
- SetErrorInfo(0, pErrorInfo);
- }
- //#ifdef _DEBUG
- // USES_CONVERSION;
- // ATLTRACE(_T("AtlReportError: Description=\"%s\" returning %x\n"), OLE2CT(lpszDesc), hRes);
- //#endif
- return (hRes == 0) ? DISP_E_EXCEPTION : hRes;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Module
-
- //Although these functions are big, they are only used once in a module
- //so we should make them inline.
-
- ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- if (pM->cbSize < sizeof(_ATL_MODULE))
- return E_INVALIDARG;
- pM->m_pObjMap = p;
- pM->m_hInst = pM->m_hInstTypeLib = pM->m_hInstResource = h;
- pM->m_nLockCnt=0L;
- pM->m_hHeap = NULL;
- InitializeCriticalSection(&pM->m_csTypeInfoHolder);
- InitializeCriticalSection(&pM->m_csWindowCreate);
- InitializeCriticalSection(&pM->m_csObjMap);
- return S_OK;
- }
-
- ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_pObjMap != NULL);
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- HRESULT hRes = S_OK;
- while (pEntry->pclsid != NULL && hRes == S_OK)
- {
- hRes = pEntry->RegisterClassObject(dwClsContext, dwFlags);
- pEntry++;
- }
- return hRes;
- }
-
- ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_pObjMap != NULL);
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- HRESULT hRes = S_OK;
- while (pEntry->pclsid != NULL && hRes == S_OK)
- {
- hRes = pEntry->RevokeClassObject();
- pEntry++;
- }
- return hRes;
- }
-
- ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_pObjMap != NULL);
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- HRESULT hRes = S_OK;
- if (ppv == NULL)
- return E_POINTER;
- while (pEntry->pclsid != NULL)
- {
- if (InlineIsEqualGUID(rclsid, *pEntry->pclsid))
- {
- if (pEntry->pCF == NULL)
- {
- EnterCriticalSection(&pM->m_csObjMap);
- if (pEntry->pCF == NULL)
- hRes = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF);
- LeaveCriticalSection(&pM->m_csObjMap);
- }
- if (pEntry->pCF != NULL)
- hRes = pEntry->pCF->QueryInterface(riid, ppv);
- break;
- }
- pEntry++;
- }
- if (*ppv == NULL && hRes == S_OK)
- hRes = CLASS_E_CLASSNOTAVAILABLE;
- return hRes;
- }
-
- ATLAPI AtlModuleTerm(_ATL_MODULE* pM)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_hInst != NULL);
- if (pM->m_pObjMap != NULL)
- {
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- while (pEntry->pclsid != NULL)
- {
- if (pEntry->pCF != NULL)
- pEntry->pCF->Release();
- pEntry->pCF = NULL;
- pEntry++;
- }
- }
- DeleteCriticalSection(&pM->m_csTypeInfoHolder);
- DeleteCriticalSection(&pM->m_csWindowCreate);
- DeleteCriticalSection(&pM->m_csObjMap);
- if (pM->m_hHeap != NULL)
- HeapDestroy(pM->m_hHeap);
- return S_OK;
- }
-
- ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_hInst != NULL);
- _ASSERTE(pM->m_pObjMap != NULL);
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- HRESULT hRes = S_OK;
- for (;pEntry->pclsid != NULL; pEntry++)
- {
- if (pCLSID == NULL)
- {
- if (pEntry->pfnGetObjectDescription() != NULL)
- continue;
- }
- else
- {
- if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
- continue;
- }
- hRes = pEntry->pfnUpdateRegistry(TRUE);
- if (FAILED(hRes))
- break;
- }
- if (SUCCEEDED(hRes) && bRegTypeLib)
- hRes = AtlModuleRegisterTypeLib(pM, 0);
- return hRes;
- }
-
- ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID)
- {
- _ASSERTE(pM != NULL);
- if (pM == NULL)
- return E_INVALIDARG;
- _ASSERTE(pM->m_hInst != NULL);
- _ASSERTE(pM->m_pObjMap != NULL);
- _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
- for (;pEntry->pclsid != NULL; pEntry++)
- {
- if (pCLSID == NULL)
- {
- if (pEntry->pfnGetObjectDescription() != NULL)
- continue;
- }
- else
- {
- if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
- continue;
- }
- pEntry->pfnUpdateRegistry(FALSE); //unregister
- }
- return S_OK;
- }
-
- ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE* pM, LPCOLESTR lpszRes,
- BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
- {
- USES_CONVERSION;
- _ASSERTE(pM != NULL);
- HRESULT hRes = S_OK;
- CComPtr<IRegistrar> p;
- if (pReg != NULL)
- p = pReg;
- else
- {
- hRes = CoCreateInstance(CLSID_Registrar, NULL,
- CLSCTX_INPROC_SERVER, IID_IRegistrar, (void**)&p);
- }
- if (SUCCEEDED(hRes))
- {
- TCHAR szModule[_MAX_PATH];
- GetModuleFileName(pM->m_hInst, szModule, _MAX_PATH);
- p->AddReplacement(OLESTR("Module"), T2OLE(szModule));
-
- if (NULL != pMapEntries)
- {
- while (NULL != pMapEntries->szKey)
- {
- _ASSERTE(NULL != pMapEntries->szData);
- p->AddReplacement((LPOLESTR)pMapEntries->szKey, (LPOLESTR)pMapEntries->szData);
- pMapEntries++;
- }
- }
- LPCOLESTR szType = OLESTR("REGISTRY");
- GetModuleFileName(pM->m_hInstResource, szModule, _MAX_PATH);
- LPOLESTR pszModule = T2OLE(szModule);
- if (HIWORD(lpszRes)==0)
- {
- if (bRegister)
- hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
- else
- hRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
- }
- else
- {
- if (bRegister)
- hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);
- else
- hRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);
- }
-
- }
- return hRes;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // TypeLib Support
-
- ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex)
- {
- _ASSERTE(pM != NULL);
- USES_CONVERSION;
- _ASSERTE(pM->m_hInstTypeLib != NULL);
- TCHAR szModule[_MAX_PATH+10];
- OLECHAR szDir[_MAX_PATH];
- GetModuleFileName(pM->m_hInstTypeLib, szModule, _MAX_PATH);
- if (lpszIndex != NULL)
- lstrcat(szModule, OLE2CT(lpszIndex));
- ITypeLib* pTypeLib;
- LPOLESTR lpszModule = T2OLE(szModule);
- HRESULT hr = LoadTypeLib(lpszModule, &pTypeLib);
- if (!SUCCEEDED(hr))
- {
- // typelib not in module, try <module>.tlb instead
- LPTSTR lpszExt = NULL;
- LPTSTR lpsz;
- for (lpsz = szModule; *lpsz != NULL; lpsz = CharNext(lpsz))
- {
- if (*lpsz == _T('.'))
- lpszExt = lpsz;
- }
- if (lpszExt == NULL)
- lpszExt = lpsz;
- lstrcpy(lpszExt, _T(".tlb"));
- lpszModule = T2OLE(szModule);
- hr = LoadTypeLib(lpszModule, &pTypeLib);
- }
- if (SUCCEEDED(hr))
- {
- ocscpy(szDir, lpszModule);
- szDir[AtlGetDirLen(szDir)] = 0;
- hr = ::RegisterTypeLib(pTypeLib, lpszModule, szDir);
- }
- if (pTypeLib != NULL)
- pTypeLib->Release();
- return hr;
- }
-
- #ifndef ATL_NO_NAMESPACE
- #ifndef _ATL_DLL_IMPL
- }; //namespace ATL
- #endif
- #endif
-
- #endif //!_ATL_DLL
-